home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
176-200
/
scopedisk192
/
unzipv3.1
/
unshrink.c
< prev
next >
Wrap
Text File
|
1995-03-19
|
4KB
|
153 lines
/* ------------------------------------------------------------- */
/*
* Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
* with partial clearing.
*
*/
void partial_clear()
{
register int pr;
register int cd;
/* mark all nodes as potentially unused */
for (cd = first_ent; cd < free_ent; cd++)
prefix_of[cd] |= 0x8000;
/* unmark those that are used by other nodes */
for (cd = first_ent; cd < free_ent; cd++) {
pr = prefix_of[cd] & 0x7fff; /* reference to another node? */
if (pr >= first_ent) /* flag node as referenced */
prefix_of[pr] &= 0x7fff;
}
/* clear the ones that are still marked */
for (cd = first_ent; cd < free_ent; cd++)
if ((prefix_of[cd] & 0x8000) != 0)
prefix_of[cd] = -1;
/* find first cleared node as next free_ent */
cd = first_ent;
while ((cd < maxcodemax) && (prefix_of[cd] != -1))
cd++;
free_ent = cd;
}
/* ------------------------------------------------------------- */
void unShrink()
{
#define GetCode(dest) READBIT(codesize,dest)
register int code;
register int stackp;
int finchar;
int oldcode;
int incode;
/* decompress the file */
maxcodemax = 1 << max_bits;
codesize = init_bits;
maxcode = (1 << codesize) - 1;
free_ent = first_ent;
offset = 0;
sizex = 0;
for (code = maxcodemax; code > 255; code--)
prefix_of[code] = -1;
for (code = 255; code >= 0; code--) {
prefix_of[code] = 0;
suffix_of[code] = code;
}
GetCode(oldcode);
if (zipeof)
return;
finchar = oldcode;
OUTB(finchar);
stackp = hsize;
while (!zipeof) {
GetCode(code);
if (zipeof)
return;
while (code == clear) {
GetCode(code);
switch (code) {
case 1:{
codesize++;
if (codesize == max_bits)
maxcode = maxcodemax;
else
maxcode = (1 << codesize) - 1;
}
break;
case 2:
partial_clear();
break;
}
GetCode(code);
if (zipeof)
return;
}
/* special case for KwKwK string */
incode = code;
if (prefix_of[code] == -1) {
stack[--stackp] = finchar;
code = oldcode;
}
/* generate output characters in reverse order */
while (code >= first_ent) {
stack[--stackp] = suffix_of[code];
code = prefix_of[code];
}
finchar = suffix_of[code];
stack[--stackp] = finchar;
/* and put them out in forward order, block copy */
if ((hsize-stackp+outcnt) < OUTBUFSIZ) {
zmemcpy(outptr,&stack[stackp],hsize-stackp);
outptr += hsize-stackp;
outcnt += hsize-stackp;
stackp = hsize;
}
/* output byte by byte if we can't go by blocks */
else while (stackp < hsize)
OUTB(stack[stackp++]);
/* generate new entry */
code = free_ent;
if (code < maxcodemax) {
prefix_of[code] = oldcode;
suffix_of[code] = finchar;
do
code++;
while ((code < maxcodemax) && (prefix_of[code] != -1));
free_ent = code;
}
/* remember previous code */
oldcode = incode;
}
}